經過前六天的痛點拆解、主管提案、技術選型,以及上篇完成的手風琴內嵌卡片(Inline Card)UI/UX Wireframe 原型設計,我們已經將 NGO 的現場需求完全摸透。
進入第二階段【規格定義與 API 開發】,我們要把這些「看得到的畫面」與「聽得到的習慣」,轉化為系統需求規格書(SRS, System Requirements Specification)與資料庫結構(Schema)。今天我們將結合 Google Notebook 作為 AI 知識庫助手,在短短 10 分鐘內產出標準 SRS,並設計一套把 Google Sheets 當作關聯式資料庫(RDB)運作的 4 大 Schema 藍圖!
傳統專案開發中,撰寫 SRS 規格書往往需要耗費 PM 好幾天的時間整理會議紀錄與草稿。現在,我們可以直接利用 Google Notebook 來高效率完成這件事。
Notebook Prompt 範例:
「請根據上傳的專案資料,整理出一份符合 IEEE 標準的『零成本智慧訂房系統系統需求規格書大綱』。請將需求明確拆解為功能性需求 (Functional Requirements, FR) 與 非功能性需求 (Non-Functional Requirements, NFR),特別標註關於 90 天邊界、12H/24H 雙時制、Reschedule Token 唯一核銷,以及手風琴內嵌卡片(Inline Card)介面的規範。」
[SRS 系統需求規格書摘要]
1. 功能性需求 (Functional Requirements)
- FR-01 【雙時制轉換】系統 UI 需支援 12H (下午 02:00) 與 24H (14:00) 顯示模式,並記憶設定。
- FR-02 【AI 語意解析】系統需整合 Gemini 3.6 Flash API,解析自然語言自動填充預約欄位。
- FR-03 【資源動態扣減】預約房間時,系統需同時檢查移動影音設備 (投影機/電視) 庫存。
- FR-04 【Token 核銷】取消 1 天前預約需自動發放 Reschedule Token (效期 60 天,上限改期 2 次)。
- FR-05 【手風琴 UI】新增與查詢介面需採用頁面內展開卡片 (Inline Card),禁止跳出式 Modal 彈窗。
2. 非功能性需求 (Non-Functional Requirements)
- NFR-01【零軟體成本】系統後端與資料庫需 100% 運行於 Google 免費生態系 (GAS + Sheets)。
- NFR-02【硬性時間邊界】前端與後端需硬性封鎖超過當前時間 + 90 天以外的預約。
- NFR-03【稽核軌跡】所有新增、取消與 Token 折抵必須寫入不可篡改的 Audit_Logs 紀錄表。
因為本專案目標是 零預算,我們不使用 PostgreSQL 或 Firebase,而是直接採用 Google Sheets 試算表 作為後端資料庫。
為了避免傳統試算表資料混亂、寫入格式不一的問題,我們以關聯式資料庫(RDB)的邏輯,設計 4 張獨立工作表(Tabs) 作為 Schema:
Bookings (預約主表)紀錄所有成功建立的預約單狀態與詳細內容。
| 欄位名稱 (Column) | 欄位 | 資料型別 (Type) | 範例資料 | 欄位約束與說明 |
|---|---|---|---|---|
booking_id |
預約單號 | String (PK) | BK-20260923-8F3A |
主鍵,唯一識別碼 |
department |
申請部門/姓名 | String | 青年服務部 - Alex |
申請者識別 |
room_id |
預約房間 ID | String (FK) | RM-A1 |
外鍵,對應 Resources |
start_time |
開始時間 | DateTime | 2026-09-23 14:00:00 |
ISO 8601 格式儲存 |
end_time |
結束時間 | DateTime | 2026-09-23 16:00:00 |
ISO 8601 格式儲存 |
equipment_ids |
附加設備 | String (JSON) | ["EQ-PROJECTOR-1"] |
JSON 陣列,動態扣減 |
token_used |
使用的改期 Token | String (FK) | TK-20260901-8A |
外鍵,折抵舊單,可為空 |
status |
預約狀態 | Enum | CONFIRMED |
CONFIRMED / CANCELLED |
created_at |
建立時間 | DateTime | 2026-09-22 10:30:00 |
系統自動生成時間戳 |
Resources (資源與設備主表)定義 NGO 組織內現有的房間與移動式影音設備庫存。
| 欄位名稱 (Column) | 欄位 | 資料型別 (Type) | 範例資料 | 欄位約束與說明 |
|---|---|---|---|---|
resource_id |
資源 ID | String (PK) | RM-A1 |
主鍵,如 RM-A1, EQ-PROJ |
resource_name |
資源名稱 | String | 活動室 A1 |
介面顯示名稱 |
type |
資源類型 | Enum | ROOM |
ROOM (房間) / EQUIPMENT (設備) |
total_quantity |
總庫存量 | Integer | 1 |
房間固定為 1,移動設備可 > 1 |
color_code |
視覺標示顏色 | String | #10B981 |
用於 RWD 看板標籤 (綠色) |
is_active |
是否啟用 | Boolean | TRUE |
維修中可設為 FALSE |
RescheduleTokens (改期令牌表)專為之前定義的「防人情套單」機制設計,追蹤每一個取消後核發的 Token 狀態。
| 欄位名稱 (Column) | 欄位 | 資料型別 (Type) | 範例資料 | 欄位約束與說明 |
|---|---|---|---|---|
token_code |
令牌代碼 | String (PK) | TK-20260901-8A |
主鍵,一對一核銷驗證碼 |
original_booking_id |
原取消預約單號 | String (FK) | BK-20260901-1A2B |
外鍵,追蹤原始訂單 |
department |
隸屬部門 | String | 青年服務部 |
限同部門或本人使用 |
expire_at |
令牌失效日期 | Date | 2026-10-31 |
硬性設定為 cancellation + 60 天 |
reschedule_count |
已改期次數 | Integer | 1 |
硬性上限 2 次,達到 2 鎖定 |
status |
令牌狀態 | Enum | ACTIVE |
ACTIVE (有效) / USED / EXPIRED |
Audit_Logs (不可篡改稽核日誌)記錄所有變更操作,確保營運公平透明,擺脫傳統紙本塗改與私下喬時間的灰色地帶。
| 欄位名稱 (Column) | 欄位 | 資料型別 (Type) | 範例資料 | 欄位約束與說明 |
|---|---|---|---|---|
log_id |
日誌 ID | String (PK) | LOG-99214 |
自動遞增或 UUID |
action_type |
操作類型 | Enum | CANCEL_BOOKING |
CREATE / CANCEL / RESCHEDULE |
operator |
操作者 | String | 青年服務部 - Alex |
執行動作的使用者 |
target_id |
操作目標 ID | String | BK-20260923-8F3A |
對應預約單號或 Token |
details |
變更詳細 JSON | String (JSON) | {"reason": "雨天取消"} |
紀錄修改細節與備註 |
timestamp |
紀錄時間 | DateTime | 2026-09-22 10:35:12 |
系統寫入時間(不可塗改) |
雖然 Google Sheets 免費又直覺,但把它當作資料庫時,工程師必須處理兩個經典坑位:
志工如果直接開啟試算表手動修改,很容易把日期格式打錯(例如把 2026-09-23 打成 9月23)。
status 欄位設為下拉選單,並鎖定特定欄位僅能由後端 Apps Script API 寫入,禁止人工直接編輯。如果 Alex 和另一個同事在同一秒鐘點擊預約「活動室 A1 14:00-16:00」,後端 API 若同時讀取試算表,可能會判定兩者都合法,進而造成「重複預約 (Overbooking)」。
LockService(互斥鎖),確保同一時間只有一個請求能寫入試算表,徹底杜絕超賣問題!今天我們利用 Google Notebook 快速收斂出了專業的 SRS 需求規格書,並設計出兼具防呆、稽核與完整關聯的 Google Sheets 4 大 Schema 藍圖。
明天再續……